//package demo.controller;
//
//import demo.util.RedisUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.web.bind.annotation.GetMapping;
//import org.springframework.web.bind.annotation.RestController;
//import redis.clients.jedis.Jedis;
//
//import java.util.Collections;
//import java.util.List;
//import java.util.UUID;
//import java.util.concurrent.TimeUnit;
//
///**
// * @author cici
// */
//@RestController
//public class GoodController6 {
//
//    final String REDIS_LOCK = "ciciLock";
//
//    @Autowired
//    private StringRedisTemplate redisTemplate;
//
//    @Value("${server.port}")
//    private String serverPort;
//
//    @GetMapping(value = "/miaosha")
//    public String goods() throws Exception {
//
//        String value = UUID.randomUUID().toString()+Thread.currentThread().getName();
//
//
//        try {
//
//            //加锁和设置时间没有原子性
////            Boolean flag = redisTemplate.opsForValue().setIfAbsent(REDIS_LOCK,value);
////            redisTemplate.expire(REDIS_LOCK,10L, TimeUnit.SECONDS);
//            //缓存续期问题
//            Boolean flag = redisTemplate.opsForValue().setIfAbsent(REDIS_LOCK,value,10L,TimeUnit.SECONDS);
//            if (!flag) {
//                return "抢锁失败。";
//            }
//
//            String res = redisTemplate.opsForValue().get("goods:001");
//            int num = res == null ? 0 : Integer.parseInt(res);
//            if (num > 0){
//                int afterNum = num - 1 ;
//                redisTemplate.opsForValue().set("goods:001",String.valueOf(afterNum));
//                System.out.println("成功购买商品，库存还剩下：" + afterNum + "，端口来自" + serverPort);
//
//                return "成功购买商品，库存还剩下：" + afterNum + "，端口来自" + serverPort;
//            }else {
//                System.out.println("商品已售罄。" + serverPort);
//            }
//            return "商品已售罄。" + serverPort;
//        }finally {
//            //并发问题的时候要注意每段代码的原子性，判断和删锁不上原子操作，用LUA脚本可以解决
//            /**
//             * 问题是不用LUA脚本，还有其他方法吗？
//             */
////            if (redisTemplate.opsForValue().get(REDIS_LOCK).equalsIgnoreCase(value)){
////                redisTemplate.delete(REDIS_LOCK);
////            }
//            //尝试用Redis的事务解决问题
////            while(true){
////                //监控，相对于mysql的乐观锁
////                redisTemplate.watch(REDIS_LOCK);
////                if (redisTemplate.opsForValue().get(REDIS_LOCK).equalsIgnoreCase(value)){
////                    //开启支持事务
////                    redisTemplate.setEnableTransactionSupport(true);
////                    //开启事务
////                    redisTemplate.multi();
////                    //放入待执行队列
////                    redisTemplate.delete(REDIS_LOCK);
////                    //提交事务
////                    List<Object> list = redisTemplate.exec();
////                    //如果失败，继续轮询
////                    if (list == null){
////                        continue;
////                    }
////                }
////                //成功则退出
////                redisTemplate.unwatch();
////                break;
////            }
//            //使用LUA脚本实现删锁的原子操作，但同时还存在缓存续时和Reids集群问题
//            Jedis jedis = RedisUtils.getJedis();
//            String script =  "if redis.all('get',KEYS[1]) == ARGV[1]" +
//            "then" +
//            "return redis.call('del',KEYS[1])" +
//            "else" +
//            "return 0" +
//            "end";
//
//            try{
//               Object o = jedis.eval(script, Collections.singletonList(REDIS_LOCK), Collections.singletonList(value));
//               if (o.toString().equals("1")){
//                   System.out.println("删锁成功。");
//               }else {
//                   System.out.println("删锁失败。");
//               }
//            }finally {
//                if (null != jedis){
//                    jedis.close();
//                }
//            }
//        }
//    }
//}
